<?php

namespace App\Service\WorkOrder\Web;

use App\Enums\BaseErrorCode;
use App\Enums\WorkOrder\ErrCode;
use App\Enums\WorkOrder\MissionEnum;
use App\Enums\WorkOrder\OrderEnum;
use App\Exceptions\Custom\CustomHttpResponseException;
use App\Exceptions\Custom\ResponseHttpException;
use App\Exports\WorkOrder\FunctionOpenExport;
use App\Http\Form\KfCashRegisterV2\KfCashRegisterV2FormAttribute;
use App\Jobs\Export\Export;
use App\Library\Rms\RmsShopApi;
use App\Models\BaseModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopContractTemplateModel;
use App\Models\OpenShop\SiteLocation\OpenShopSiteLocationModel;
use App\Models\WorkOrder\WorkOrderApplyContentModel;
use App\Models\WorkOrder\WorkOrderApplyMainModel;
use App\Models\WorkOrder\WorkOrderApplyManagerModel;
use App\Models\WorkOrder\WorkOrderMissionModel;
use App\Models\WorkOrder\WorkOrderOperateLogModel;
use App\Models\WorkOrder\WorkOrderUserRoleModel;
use App\Remote\Rms\RmsShopRemote;
use App\Service\OpenShop\SiteLocation\SiteLocationService;
use App\Service\WorkOrder\Mission\MissionNoticeService;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use App\Service\WorkOrder\Permission\PermissionService;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
use Maatwebsite\Excel\Facades\Excel;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class OrderListService
{
    public function orderPanel(int $userId): array
    {
        return [

            // 我处理中
            'myDealing'       => WorkOrderMissionModel::query()
                                                      ->where('dealUid', $userId)
                                                      ->where('missionStatus', MissionEnum::MISSION_STATUS_0)
                                                      ->whereHas("applyMainRel")
                                                      ->distinct('workOrderNo')
                                                      ->count(),

            // 我已解决的
            'myFinish'        => WorkOrderMissionModel::query()
                                                      ->where('dealUid', $userId)
                                                      ->where('missionStatus', MissionEnum::MISSION_STATUS_1)
                                                      ->whereHas("applyMainRel")
                                                      ->distinct('workOrderNo')
                                                      ->count(),
            // 处理人列表
            'dealUidLists'    => WorkOrderUserRoleModel::query()
                                                       ->groupBy('userId')
                                                       ->select('userId', 'name')
                                                       ->get(),

            // 二级问题类型
            'problemChildIds' => collect(OrderEnum::TYPE_RELATION_MAP)->map(function ($children, $problemPid) {
                return [
                    'value'    => $problemPid,
                    'label'    => OrderEnum::PROBLEM_PID_TEXT[$problemPid] ?? '',
                    'children' => collect($children)->map(function ($label, $value) {
                        return [
                            'value' => $value,
                            'label' => $label,
                        ];
                    })->values(),
                ];
            })->values()->toArray(),
        ];
    }

    /**
     *  工单池：筛选角色对应的工单，比如品质异常问题 对应品控处理人，工单池中只需要显示未完成的工单
     * 所有工单：展示角色权限下所有工单
     * 我处理中：展示工单处理节点为该用户的工单，不展示完成后的工单
     * 我已解决：展示工单处理节点包含自己但自己的环节已经结束，进入下一环节的工单，不一定全部是已完成状态的工单
     * 已关闭的：展示工单处理节点包含自己但是已经由自己或其他环节人员关闭的工单。
     */
    const TAB_TYPE_0 = 0; // 所有工单
    const TAB_TYPE_1 = 1; // 我处理中
    const TAB_TYPE_2 = 2; // 我已解决
    const TAB_TYPE_3 = 3; // 已关闭的
    const TAB_TYPE_4 = 4; // 工单池

    /**
     * 工单池列表
     *
     *
     *
     *
     * @param array $data
     * @param int $userId
     * @param string $export
     * @return array
     * @throws GuzzleException
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     * @throws \Maatwebsite\Excel\Exceptions\NoTypeDetectedException
     * @throws \OSS\Core\OssException
     */
    public function orderLists(array $data, int $userId, string $export = "false"): array
    {
        $shopIds            = $data['shopIds'];
        $step               = $data['step'];
        $nowDealUid         = $data['nowDealUid'];
        $dealUid            = $data['dealUid'];
        $workOrderNo        = $data['workOrderNo'];
        $problemPid         = $data['problemPid'];
        $pageSize           = $data['pageSize'];
        $pageNum            = $data['pageNum'];
        $priority           = $data['priority'];
        $tabType            = $data['tabType'];
        $problemChildIdsStr = $data['problemChildIds'];
        $submitTimeStart    = $data['submitTimeStart'];
        $submitTimeEnd      = $data['submitTimeEnd'];
        $updateTimeStart    = $data['updateTimeStart'];
        $updateTimeEnd      = $data['updateTimeEnd'];
        $shopSearch         = $data['shopSearch'];
        $sourceType         = $data['sourceType'];
        $goodsName          = $data['goodsName'];
        $shopPattern        = $data['shopPattern'] ?? '';

        if ($problemChildIdsStr) {
            $problemChildIdsArr = explode(',', $problemChildIdsStr);
        } else {
            $problemChildIdsArr = [];
        }


        // 权限
        $permission = $data['permission'];//(new PermissionService())->orderLists($userId);

        $paginates = WorkOrderApplyMainModel::query()
                                            ->with([
                                                'missionsRel',
                                                'contentRel',
                                                'openShopMainProcessRel' => function ($q) {
                                                    $q->with([
                                                        'signOrderRel.contractRel',
                                                        'openShopSiteLocationRel'
                                                    ]);
                                                }
                                            ])
                                            ->where('step', '>', MissionEnum::STEP_1)
                                            ->when(!$permission['isAll'], function ($query) use ($permission) {
                                                $query->whereRaw($permission['rawSql']);
                                            })
                                            ->when(strlen($shopPattern), function ($query) use ($shopPattern) {
                                                $shopPatternArr = explode(',', $shopPattern);
                                                if (count($shopPatternArr) == 1) {
                                                    switch ($shopPattern) {
                                                        case OpenShopSiteLocationModel::SHOP_PATTERN_TWO:
                                                            $query->whereRaw("work_order_apply_main.shopId in (select open_shop_main_process.shopId from open_shop_main_process where open_shop_main_process.orderNo in (select open_shop_site_locations.orderNo from open_shop_site_locations where shopPattern != 3 and source = 0 and isDeleted = 0))");
                                                            break;
                                                        case OpenShopSiteLocationModel::SHOP_PATTERN_THREE:
                                                            $query->whereRaw("work_order_apply_main.shopId in (select open_shop_main_process.shopId from open_shop_main_process where open_shop_main_process.orderNo in (select open_shop_site_locations.orderNo from open_shop_site_locations where shopPattern = 3 and source = 0 and isDeleted = 0))");
                                                            break;
                                                        default:
                                                    }
                                                }
                                            })
                                            ->when(strlen($sourceType) > 0, function ($query) use ($sourceType) {
                                                $query->where("sourceType", $sourceType);
                                            })
                                            ->when($tabType > 0,
                                                function ($query) use ($tabType, $userId, $permission) {
                                                    if ($tabType == self::TAB_TYPE_1) {
                                                        $child = WorkOrderMissionModel::query()
                                                                                      ->where('dealUid', $userId)
                                                                                      ->where('missionStatus',
                                                                                          MissionEnum::MISSION_STATUS_0)
                                                                                      ->select('workOrderNo');


                                                        $query->whereRaw("workOrderNo in (" . BaseModel::toSqlWithParam($child) . ')');
                                                    } elseif ($tabType == self::TAB_TYPE_2) {
                                                        $child = WorkOrderMissionModel::query()
                                                                                      ->where('dealUid', $userId)
                                                                                      ->where('missionStatus',
                                                                                          MissionEnum::MISSION_STATUS_1)
                                                                                      ->select('workOrderNo');

                                                        $query->whereRaw("workOrderNo in (" . BaseModel::toSqlWithParam($child) . ')');
                                                    } elseif ($tabType == self::TAB_TYPE_3) {

                                                        // 没有全部权限的时候，就按需求来只看自己相关的关闭单
                                                        if (!$permission['isAll']) {
                                                            $child = WorkOrderMissionModel::query()
                                                                                          ->where('dealUid', $userId)
                                                                                          ->select('workOrderNo');

                                                            $query->whereRaw("workOrderNo in (" . BaseModel::toSqlWithParam($child) . ')');
                                                        }

                                                        $query->where('status', OrderEnum::MAIN_STATUS_CLOSE)->withoutGlobalScope('isDel');

                                                    } elseif ($tabType == self::TAB_TYPE_4) {
                                                        $query->where('status', OrderEnum::MAIN_STATUS_ING);
                                                    }


                                                })
                                            ->when($shopIds, function ($query) use ($shopIds) {
                                                $query->whereIn('shopId', explode(',', $shopIds));
                                            })
                                            ->when($step, function ($query) use ($step) {
                                                if ($step == 1000) {
                                                    $query->where('merchantConfirmFinishStatus',
                                                        WorkOrderApplyMainModel::MERCHANT_CONFIRM_FINISH_TYPE_SYSTEM);
                                                } else {
                                                    $query->where('step', $step);
                                                }
                                            })
                                            ->when($nowDealUid, function ($query) use ($nowDealUid) {

                                                $child = WorkOrderMissionModel::query()
                                                                              ->where('dealUid', $nowDealUid)
                                                                              ->where('missionStatus',
                                                                                  MissionEnum::MISSION_STATUS_0)
                                                                              ->select('workOrderNo');

                                                $query->whereRaw("workOrderNo in (" . BaseModel::toSqlWithParam($child) . ')');
                                            })
                                            ->when($dealUid, function ($query) use ($dealUid) {

                                                $child = WorkOrderMissionModel::query()
                                                                              ->where('dealUid', $dealUid)
                                                                              ->select('workOrderNo');

                                                $query->whereRaw("workOrderNo in (" . BaseModel::toSqlWithParam($child) . ')');
                                            })
                                            ->when($workOrderNo, function ($query) use ($workOrderNo) {
                                                $query->where('workOrderNo', $workOrderNo);
                                            })
                                            ->when($problemPid, function ($query) use ($problemPid, $goodsName) {
                                                $query->where('problemPid', $problemPid);
                                                if ($problemPid == OrderEnum::PROBLEM_PID_2 && !empty($goodsName)) {
                                                    $query->whereIn("workOrderNo", function ($query) use ($goodsName) {
                                                        $query->select("workOrderNo")
                                                              ->from((new WorkOrderApplyContentModel())->getTable())
                                                              ->whereRaw("JSON_EXTRACT(content, '$**.goods_name') LIKE '%$goodsName%'")
                                                            ->orWhereRaw("JSON_EXTRACT(content, '$**.tag_name') LIKE '%$goodsName%'");
                                                    });
                                                }
                                            })
                                            ->when(is_numeric($priority) && $priority > 0,
                                                function ($query) use ($priority) {
                                                    $query->where('priority', $priority);
                                                })
                                            ->when($problemChildIdsArr, function ($query) use ($problemChildIdsArr) {
                                                $query->whereIn('problemChildId', $problemChildIdsArr);
                                            })
                                            ->when(validateDateTimeFormat($submitTimeStart, "Y-m-d"),
                                                function ($query) use ($submitTimeStart) {
                                                    $query->where("createdAt", ">=", strtotime($submitTimeStart));
                                                })
                                            ->when(validateDateTimeFormat($submitTimeEnd, "Y-m-d"),
                                                function ($query) use ($submitTimeEnd) {
                                                    $query->where("createdAt", "<",
                                                        strtotime("+1 day", strtotime($submitTimeEnd)));
                                                })
                                            ->when(validateDateTimeFormat($updateTimeStart, "Y-m-d"),
                                                function ($query) use ($updateTimeStart) {
                                                    $query->where("updatedAt", ">=", strtotime($updateTimeStart));
                                                })
                                            ->when(validateDateTimeFormat($updateTimeEnd, "Y-m-d"),
                                                function ($query) use ($updateTimeEnd) {
                                                    $query->where("updatedAt", "<",
                                                        strtotime("+1 day", strtotime($updateTimeEnd)));
                                                })
                                            ->when($shopSearch, function ($query) use ($shopSearch) {
                                                $shopInfos = RmsShopRemote::getShopInfoByLikeSearch($shopSearch);
                                                $shopIds   = array_column($shopInfos["shopInfo"], "id");
                                                if ($shopIds) {
                                                    $query->whereIn('shopId', $shopIds);
                                                } else {
                                                    $query->where('shopId', 0);
                                                }
                                            })
                                            ->selectRaw("*, (completeTime>0) as isFinish")
                                            ->orderBy('createdAt', "desc")
                                            ->orderBy('isFinish')
                                            ->orderByDesc('priority')
                                            ->when(
                                                $export == "true",
                                                function ($query) {
                                                    return $query->get();
                                                },
                                                function ($query) use ($pageNum, $pageSize) {
                                                    return $query->paginate($pageSize, ['*'], 'pageNum', $pageNum);
                                                }
                                            );

        // 店铺信息
        if ($paginates->count()) {
            $shopInfos = (new RmsShopApi())->getShopByIds($paginates->pluck('shopId')->unique()->toArray(),
                    ['id', 'name', 'shopCode', 'councilorId'])['data']['shopList'] ?? [];
        } else {
            $shopInfos = [];
        }
        $shopInfos = collect($shopInfos)->keyBy('id');

        if ($export == "true") {
            if (empty($problemPid)) {
                throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "工单分类信息必选");
            }

            $fileNamePrefix = (OrderEnum::PROBLEM_PID_TEXT[$problemPid] ?? '-') . '-' . date('Y-m-d') . '_' . date('H:i');

            return excelDownload(
                new FunctionOpenExport($problemPid, $paginates, $shopInfos, $submitTimeStart, $submitTimeEnd,
                    $problemChildIdsArr),
                $fileNamePrefix
            );
        } else {
            // 负责人
            $managers = [];
            WorkOrderApplyManagerModel::query()
                                      ->whereIn('workOrderNo', $paginates->pluck('workOrderNo'))
                                      ->get()
                                      ->each(function ($item) use (&$managers) {
                                          if ($item->role == WorkOrderUserRoleModel::ROLE_TYPE_1) {

                                              // 客服
                                              $managers[$item->workOrderNo][0][] = $item->managerName;
                                          } else {

                                              // 其他
                                              $managers[$item->workOrderNo][1][] = $item->managerName;
                                          }
                                      });

            // 用户角色
            $roles = WorkOrderUserRoleModel::query()->where('userId', $userId)->pluck('role')->toArray();

            $lists = $paginates->map(function ($item) use ($shopInfos, $managers, $userId, $roles) {
                $goodsName    = [];//产品名称
                $goodsCode    = [];//商品编码
                $goodsTagName = [];//统一名称

                // 非法人收款标记
                $tags          = []; // 前端显示标记数组
                $unCorporation = 0; // 默认0 2-非法人
                if (isset($item->contentRel) && $item->contentRel) {
                    switch ($item->problemPid) {
                        case OrderEnum::PROBLEM_PID_1:
                        case OrderEnum::PROBLEM_PID_2:
                            $errJdeCodes = WorkOrderApplyContentModel::getContent($item->contentRel)
                                                                     ->get("errJdeCodes", []);
                            if ($errJdeCodes) {
                                $goodsName    = array_unique(array_column($errJdeCodes, 'goods_name'));
                                $goodsCode    = array_unique(array_column($errJdeCodes, 'goods_code'));
                                $goodsTagName = array_unique(array_column($errJdeCodes, 'tag_name'));
                            }
                            break;
                        case OrderEnum::PROBLEM_PID_5:
                            $payeeType = WorkOrderApplyContentModel::getContent($item->contentRel)
                                ->get('payeeType', 0);
                            if ($payeeType == KfCashRegisterV2FormAttribute::PAYEE_TYPE_UN_CORPORATION) {// 其他人收款
                                $unCorporation = KfCashRegisterV2FormAttribute::PAYEE_TYPE_UN_CORPORATION;
                                $tags[]        = '非法人';
                            }
                            break;
                        default:
                            $goodsName = $goodsCode = $goodsTagName = [];
                    }
                }
                $mode = attributeGet($item, "openShopMainProcessRel.signOrderRel.contractRel.mode", 0);
                return [
                    'workOrderNo'        => $item->workOrderNo,
                    'problemPidText'     => $item->problemChildIdTextShort,
                    'problemChildIdText' => $item->problemChildIdText,
                    'shopId'             => $item->shopId,
                    'shopPattern'        => 0,
                    'shopPatternStr'     => '',
                    'patternType'        => '',
                    'patternTypeStr'     => '',
                    'tagLocation'        => optional($item->openShopMainProcessRel)->openShopSiteLocationRel && SiteLocationService::tagLocationStatus(optional($item->openShopMainProcessRel)->openShopSiteLocationRel),
                    'shopCode'           => $shopInfos[$item->shopId]['shopCode'] ?? '',
                    'shopName'           => $shopInfos[$item->shopId]['name'] ?? '',
                    'createdAt'          => date('Y-m-d H:i:s', $item->createdAt->timestamp),
                    'updatedAt'          => date('Y-m-d H:i:s', $item->updatedAt->timestamp),
                    'step'               => $item->step,
                    'stepText'           => $item->stepText,
                    'priority'           => $item->priority,
                    'priorityText'       => $item->priorityText,
                    'managerNames'       => implode(',', $managers[$item->workOrderNo][1] ?? []),
                    'serviceNames'       => implode(',', $managers[$item->workOrderNo][0] ?? []),
                    'showClose'          => self::showClose($item, $userId),
                    'showGrab'           => self::showGrab($item, $userId, $roles),
                    'isRejected'         => (bool)$item->childStep,
                    'goodsName'          => $goodsName,//产品名称
                    'goodsCode'          => $goodsCode,// 商品编码
                    'goodsTagName'       => $goodsTagName,// 统一名称
                    'mode'               => $mode,
                    "modeText"           => OpenShopContractTemplateModel::MODE_MAP_TEXT[$mode] ?? "-",
                    'unCorporation'      => $unCorporation,
                    'tags'               => $tags,// 标签
                ];
            });

            return [
                'lists'    => $lists,
                'pageNum'  => $pageNum,
                'pageSize' => $pageSize,
                'count'    => $paginates->total(),
            ];
        }
    }

    /**
     * 是否能关闭订单
     * @param WorkOrderApplyMainModel $applyMain
     * @param int $userId
     * @return int
     */
    public static function showClose(WorkOrderApplyMainModel $applyMain, int $userId): int
    {
        // 订单不处于进行中
        if ($applyMain->status != OrderEnum::MAIN_STATUS_ING) {
            return 0;
        }

        // 功能开通可直接关闭
        if ($applyMain->problemPid == OrderEnum::PROBLEM_PID_5) {
            return 1;
        }

        // 有待处理的任务
        $missions = $applyMain->missionsRel
            ->where('missionStatus', MissionEnum::MISSION_STATUS_0)
            ->where('dealUid', $userId)
            ->count();
        if (!$missions) {
            return 0;
        }

        return 1;
    }

    public static function closeWorkOrderRole(WorkOrderApplyMainModel $order, int $uid): int
    {
        $step = $order->step;

        if (in_array($step, [MissionEnum::STEP_1, MissionEnum::STEP_2, MissionEnum::STEP_3])) {
            return WorkOrderUserRoleModel::ROLE_TYPE_1;
        }

        if ($order->isFunctionWaiMaiOpen()) {
            $apply = WorkOrderApplyManagerModel::query()
                                               ->where('workOrderNo', $order->workOrderNo)
                                               ->where('status', WorkOrderApplyManagerModel::STATUS_ON)
                                               ->where('managerId', $uid)
                                               ->where('role', WorkOrderUserRoleModel::ROLE_TYPE_7)
                                               ->first();
            if ($apply) {
                return WorkOrderUserRoleModel::ROLE_TYPE_7;
            }
        }

        return OrderEnum::PROBLEM_PID_TO_ROLE[$order->problemPid] ?? 0;
    }

    /**
     * 是否展示抢单
     * @param WorkOrderApplyMainModel $applyMain
     * @param int $userId
     * @param array $roles
     * @return int
     */
    public static function showGrab(WorkOrderApplyMainModel $applyMain, int $userId, array $roles)
    {
        // 订单不处于进行中
        if ($applyMain->status != OrderEnum::MAIN_STATUS_ING) {
            return 0;
        }

        //外开通卖类型，客服自动批，不抢单
        if ($applyMain->isFunctionWaiMaiOpen()){
            return  0;
        }

        // 不处于待抢单状态
        if (!in_array($applyMain->step, [MissionEnum::STEP_3, MissionEnum::STEP_4])) {
            return 0;
        }

        //问题反馈 - 客服审核 修改为抢单类型
        if (in_array($applyMain->problemPid, [
                OrderEnum::PROBLEM_PID_1,
                OrderEnum::PROBLEM_PID_2,
                OrderEnum::PROBLEM_PID_4
            ]) && $applyMain->step == MissionEnum::STEP_3) {
            $dealUids = WorkOrderApplyManagerModel::getMangerIdsByRole($applyMain->workOrderNo,
                WorkOrderUserRoleModel::ROLE_TYPE_1);
            if (!$dealUids) {
                $userIds = WorkOrderUserRoleModel::query()->where('role', WorkOrderUserRoleModel::ROLE_TYPE_1)
                                                 ->pluck('userId')->toArray();
                if ($userId && in_array($userId, $userIds)) {//当前人员是客服
                    return 1;
                }
            }
        }

        // 校验一级类型
        if (!$applyMain->isFunctionWaiMaiOpen() && !in_array($applyMain->problemPid, OrderEnum::GRAB_PIDS)) {
            return 0;
        }

        // 重复抢单
        if ($applyMain->managerRel->where('managerId', $userId)
                                  ->where('role', '!=', WorkOrderUserRoleModel::ROLE_TYPE_1)->count()) {
            return 0;
        }

        // 用户角色
        if (!$applyMain->isFunctionWaiMaiOpen()) {
            $problemPid  = $applyMain->problemPid;
            $problemRole = OrderEnum::PROBLEM_PID_TO_ROLE[$problemPid] ?? 0;
            if (!in_array($problemRole, $roles)) {
                return 0;
            }
        }

        return 1;
    }

    /**
     * 抢单
     * @param string $workOrderNo
     * @param int $userId
     * @return void
     */
    public function grabOrder(string $workOrderNo, int $userId): void
    {
        $order = WorkOrderApplyMainModel::query()->where('workOrderNo', $workOrderNo)->first();
        if (!$order) {
            throw new CustomHttpResponseException(ErrCode::errCodeTrans(ErrCode::CODE_ERR_WORK_ORDER_NO));
        }

        // 订单阶段
        if (!in_array($order->step,
            [MissionEnum::STEP_1, MissionEnum::STEP_2, MissionEnum::STEP_3, MissionEnum::STEP_4])) {
            throw new CustomHttpResponseException(ErrCode::errCodeTrans(ErrCode::CODE_ERR_STEP_GRAB));
        }

        // 问题反馈 - 客服审核 修改为抢单类型 每次请求需先判断是否有客服，否则新增客服
        if (in_array($order->problemPid, [
                OrderEnum::PROBLEM_PID_1,
                OrderEnum::PROBLEM_PID_2,
                OrderEnum::PROBLEM_PID_4
            ]) && $order->step == MissionEnum::STEP_3) {
            $dealUids = WorkOrderApplyManagerModel::getMangerIdsByRole($workOrderNo,
                WorkOrderUserRoleModel::ROLE_TYPE_1);
            if (!$dealUids) {
                $userIds = WorkOrderUserRoleModel::query()->where('role', WorkOrderUserRoleModel::ROLE_TYPE_1)
                                                 ->pluck('userId')->toArray();
                if ($userId && in_array($userId, $userIds)) {//当前人员是客服
                    // 抢
                    DB::beginTransaction();
                    WorkOrderApplyManagerModel::add($workOrderNo, WorkOrderUserRoleModel::ROLE_TYPE_1, $userId);
                    WorkOrderMissionModel::add($workOrderNo, MissionEnum::STEP_2, $userId);
                    WorkOrderApplyMainModel::saveStep($workOrderNo, MissionEnum::STEP_2);
                    DB::commit();
                }
                return;
            }
        }

        // 问题类型
        if (!in_array($order->problemPid, OrderEnum::GRAB_PIDS)) {
            throw new CustomHttpResponseException(ErrCode::errCodeTrans(ErrCode::CODE_ERR_PROBLEM_PID_GARB));
        }

        // 工单对应的负责人角色
        if (!$order->isFunctionWaiMaiOpen()) {
            $problemPid  = $order->problemPid;
            $problemRole = OrderEnum::PROBLEM_PID_TO_ROLE[$problemPid] ?? 0;
            if (!$problemRole) {
                throw new CustomHttpResponseException(ErrCode::errCodeTrans(ErrCode::CODE_ERR_PROBLEM_PID_TO_ROLE));
            }
        } else {
            $problemRole = WorkOrderUserRoleModel::ROLE_TYPE_6;
        }
        // 用户角色检查
        $userRole = WorkOrderUserRoleModel::query()->where('userId', $userId)->where('role', $problemRole)->count();
        if (!$userRole) {
            throw new CustomHttpResponseException(ErrCode::errCodeTrans(ErrCode::CODE_ERR_USER_NOT_ROLE));

        }

        // 重复抢单
        $repeatGrab = WorkOrderApplyManagerModel::query()
                                                ->where('workOrderNo', $workOrderNo)
                                                ->where('managerId', $userId)
                                                ->where('role', $problemRole)
                                                ->count();

        if ($repeatGrab) {
            throw new CustomHttpResponseException(ErrCode::errCodeTrans(ErrCode::CODE_ERR_REPEAT_GRAB));
        }

        // TODO 通用更新任务状态
        if ($order->isFunctionWaiMaiOpen()) {
            //外卖客服阶段 自动审核 不允许抢
            throw new CustomHttpResponseException(ErrCode::errCodeTrans(ErrCode::CODE_ERR_PROBLEM_PID_GARB));
            // 抢
            DB::beginTransaction();
            WorkOrderApplyManagerModel::add($workOrderNo, $problemRole, $userId);
            WorkOrderMissionModel::add($workOrderNo, MissionEnum::STEP_1, $userId, MissionEnum::MISSION_STATUS_1);
            WorkOrderMissionModel::add($workOrderNo, MissionEnum::STEP_2, $userId);
            WorkOrderApplyMainModel::saveStep($workOrderNo, MissionEnum::STEP_2);
            DB::commit();
        } else {
            // 抢
            DB::beginTransaction();
            WorkOrderApplyManagerModel::add($workOrderNo, $problemRole, $userId);
            WorkOrderMissionModel::add($workOrderNo, MissionEnum::STEP_3, $userId, MissionEnum::MISSION_STATUS_1);
            WorkOrderMissionModel::add($workOrderNo, MissionEnum::STEP_4, $userId);
            WorkOrderApplyMainModel::saveStep($workOrderNo, MissionEnum::STEP_4);
            DB::commit();
        }

        //日志 - 客服抢单
        WorkOrderOperateLogModel::generateOperateLog(
            $workOrderNo,
            $order->step,
            WorkOrderOperateLogModel::TYPE_2,
            request()->user()->username,
            request()->user()->id
        );
    }
}
